// cf-398b
// 题意：给定n*n(<=2000)的棋盘，初始都是白色，然后已知m个是黑色，现在
//       要将这个棋盘染成好看的，按照以下步骤：
//         1.如果每一行和每一列都至少有一个黑色的格子，就结束;
//         2.不然就等概率的选一个格子，如果是白色就画一分钟染成黑色，
//           否则就休息一分钟，然后到第1步。
//       求染成好看的时间的期望。
//
// 题解：其实仔细分析下，行列之间是没有影响的，所以就很简单了。
//       令dp[x][y]表示行有x行还没满足，列有y列还没满足的期望，然后
//       dp[x][y] = x/n * y/n * (dp[x-1][y-1]+1) + x/n * (n-y)/n * (dp[x-1][y] + 1)
//                      + (n-x)/n * y/n * (dp[x-1][y] + 1) + (n-x)/n * (n-y)/n * (dp[x][y] + 1)
//       记忆化一下就行。
//
// run: $exec < input
#include <iostream>
#include <iomanip>
#include <unordered_set>

int const maxn = 2007;
double f[maxn][maxn];
int n, m;
std::unordered_set<int> row;
std::unordered_set<int> col;

double dfs(int x, int y)
{
	if (x < 0 || y < 0) return 0;
	if (f[x][y] >= 0) return f[x][y];
	if (!x && !y) return 0;
	double t11 = dfs(x - 1, y - 1);
	double t10 = dfs(x - 1, y);
	double t01 = dfs(x, y - 1);
	double ret = x * y / (double)(n * n) * (t11 + 1);
	ret += x * (n - y) / (double)(n * n) * (t10 + 1);
	ret += (n - x) * y / (double)(n * n) * (t01 + 1);
	ret += (n - x) * (n - y) / (double)(n * n);
	ret /= (n * (x + y) - x * y) / (double)(n * n);
	return f[x][y] = ret;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 0; i <= n; i++)
		for (int j = 0; j <= n; j++) f[i][j] = -1;
	for (int i = 0, x, y; i < m; i++) {
		std::cin >> x >> y;
		row.insert(x);
		col.insert(y);
	}
	std::cout << std::fixed << std::setprecision(9) << dfs(n - row.size(), n - col.size()) << '\n';
}

